//----------------------------------------------------------------------------
//  ,-.
// /_\___ ,   Ninja Framework
// '  ___\    (C) Riccardo Capra - http://riccar.do
//  //   \\
//----------------------------------------------------------------------------
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//----------------------------------------------------------------------------

#ifndef NJ_LOCKER_H
#	define NJ_LOCKER_H

#	include "NjNinjaSyncLib.h"
#	include "NjFundamentalMacros.h"

	/// \brief Implements a scoped locker for the synchronization object \em tSyncObject
	/// \param tSyncObject the synchronization primitive. It should implement methods Lock and Unlock
	template<typename tSyncObject>
	class NjLocker
	{
	public:
		typedef tSyncObject SyncObject;

		/// \brief Creates a NjLocker instance and immediately locks \em kSyncObject
		/// \param kSyncObject The synchronization object to be locked
		NjLocker(SyncObject & kSyncObject);

		/// \brief Creates a NjLocker instance and immediately locks \em pSyncObject, if not NJ_NULL
		/// \param pSyncObject The synchronization object to be locked
		NjLocker(SyncObject * pSyncObject);

		/// \brief Destroys NjLocker and calls NjLocker::Unlock
		~NjLocker();

		/// \brief If \em m_pSyncObject is not NJ_NULL, will call tSyncObject::Unlock
		///
		/// If called multiple times, just the first Unlock call has effect
		void Unlock();

	private:
		NJ_DISABLE_DEFAULT_CONSTRUCTOR(NjLocker);
		NJ_DISABLE_COPY(NjLocker);

		/// \brief The pointed synchronization object passed during construction
		SyncObject * m_pSyncObject;
	};

#	include "NjAssert.h"
#	include "NjLocker_inline.h"

#endif // NJ_LOCKER_H
